package com.zhenai.bcus.user.filter;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.zhenai.bcus.user.constant.UserConstants;
import com.zhenai.bcus.user.context.LoginUserContext;
import com.zhenai.bcus.user.vo.LoginUserVO;
import com.zhenai.framework.base.context.ControlContext;
import com.zhenai.framework.base.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

/**
 * 接入Common Request并存入ThreadContext
 *
 * @author wangYan
 */
@Slf4j
@Component
@Activate(group = CommonConstants.PROVIDER, order = Integer.MAX_VALUE)
public class UserTokenProviderContextFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        try {

            MDC.put(UserConstants.USER_ID, null);
            RequestContext.remove(UserConstants.USER_ID);
            String userStr = invocation.getAttachment(UserConstants.USER_ID);
            if (StringUtils.isNotBlank(userStr)) {
                Long userId = Long.valueOf(userStr);
                RequestContext.put(UserConstants.USER_ID, userId);
                MDC.put(UserConstants.USER_ID, String.valueOf(userId));
            }

            LoginUserContext.setUser(null);
            String userInfoStr = RpcContext.getContext().getAttachment(UserConstants.USER_INFO);
            if (StringUtils.isNotBlank(userInfoStr)) {
                LoginUserVO userVO = JSONObject.parseObject(userInfoStr, LoginUserVO.class);
                if (ObjectUtil.isNotEmpty(userVO) && ObjectUtil.isNotEmpty(userVO.getUserId()) && userVO.getUserId().toString().equals(userStr)) {
                    LoginUserContext.setUser(userVO);
                } else {
                    log.info("用户信息不匹配 userId:{} userInfo:{}", userStr, userInfoStr);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            return invoker.invoke(invocation);
        } finally {
            RequestContext.clear();
            ControlContext.clear();
            RpcContext.getContext().clearAttachments();
            LoginUserContext.remove();
        }
    }
}
